查看原文
其他

深入mysql的innodb存储引擎之文件结构

黎杜 非科班的科班 2020-09-07

文件分类

在mysql底层中,有各种的文件来构成innodb存储引擎的一部分,主要包含这几类文件:

  1. 参数文件:在mysql启动时,指定初始化的一些参数文件,例如初始化某些结构的大小。

  2. 日志文件:记录mysql执行sql操作的日志存储的文件。如:错误日志、慢查询日志文件、查询日志文件、二进制日志文件等

  3. socket文件:主要是UNIX环境是连接本地的mysql需要使用socket文件。

  4. pid文件:mysql实例进程ID存储的文件。

  5. mysql表结构文件:定义mysql表结构的文件。

  6. 存储引擎文件:主要用来存储mysql的表数据和索引的文件。

参数文件

当mysql实例启动的时候就会去参数配置文件中,读取各种初始化参数,如用来寻找定义各种数据库配置参数所在位置的配置文件(如my.cnf文件用来储存数据文件所在的文件、错误日志文件所在的位置、socket文件所在的位置等),还有就是定义某些结构大小的配置参数的配置文件。

mysql默认会在启动的时候按照这些文件路径去寻找这些配置参数文件,进而初始化mysql实例,我们也可以通过mysql --help|grep my.cnf来查看my.cnf文件所在的路径,如下图所示:


我的my.cnf的文件路径是/etc/my.cnf,然后cat一下:

这里便是记录了数据文件的路径、socket文件所在的路径、log日志所在的文件路径、以及mysql实例进程pid存储的路径。

在mysql的配置我配置文件中参数的存储是以key/value的形式进行存储的。例如:在innodb中innodb_buffer_pool_size参数,此参数表示mysql缓冲池的大小,可以通过如下途径进行查看:

参数类型

在mysql中参数主要分为这两类,一个是动态参数,另一个是静态参数。动态参数意味着在mysql实例运行中可以进行修改,而静态参数意味着整个mysql实例运行的生命周周期中都不能修改。

我们常用的是动态参数,例如我们熟悉的autocommit,事务等级参数,直接set autocommit=0。对于静态参数,例如我们上面看到的my.cnf文件中的datadir数据文件路径就是静态参数,修改静态参数会直接报错。

对于动态参数又分为基于全局(global)还是还是会话(session)两类,可以通过set @@global|@@session.动态参数=某值,来改变参数。例如:set @@global.read_buffer_size=1048567

日志文件

日志文件记录着操作数据库执行sql的各种日志记录,以及出现错误的错误日志记录。日志文件主要包含以下几类:

  1. 错误日志:对于数据库执行某些操作失败,记录的错误日志记录,以及,某些操作的警告也会记录在这里。

  2. 二进制日志:记录对mysql数据库更改的所有操作,但是不包含select、show操作,因为这两类并没有对数据库进行修改操作。

  3. 慢查询日志:对于达到mysql自定义慢查询范围的sql语句,就会记录在这个日志中,对于检测那些sql查询耗时是比较有用的。

  4. 查询日志:对于mysql的所有的查询记录都会记录在这个日志文件中。

错误日志文件

错误无日志文件在mysql实例启动运行关闭的时候都会进行记录,我们可以通过以下的方式查看错误日志记录的位置。一个是通过上面的my.cnf文件中可以找到错误日志日志文件的路径位置,另一个可以通通过以下命令进行查找:


该文件记录着错误信息,我们可以借助该文件很好的发现问题。当数据库不能重启的时候,通过查找该错误日志文件可以帮助我们解决问题。
慢查询日志

在mysql中有一个动态参数long_query_time表示慢查询的阈值,表示当执行的sql超过这个这个参数的时间,就数据慢查询的范围就会将此纪录存入该日志中,该值默认为10,通以下命令进行查看。

在实际的开发中,一般不会有超过10秒的的sql,所以我们将该值可以设置小一点,设置为1秒,通过命令 SET long_query_time=1将该值设置为1秒,但是默认慢查询的日志记录功能是关闭的。如下图所示:


通过命令SET GLOBAL slow_query_log=ON将该功能开启,最后做一个测试执行sql:select sleep(10);然后来到mysql的datadir目录下就会有该慢查询文件

执行cat + 改文件名,就可以看到该sql执行的时间,以及执行慢的sql语句:

另外通过设置log_queries_not_using_indexes参数,也可以将没有使用索引的sql记录收到该文件中。
查询日志

查询日志文件记录了所有mysql数据库的操作信息,无论请求是否正确。可以通过如下命令查看的日志的位置:

二进制日志

记录了所有的对mysql数据库修改的操作,但是不包含selectshow这类,因为这类没有对数据库进行修改,若是想记录select和show操作,只能使用查询日志

二进制日志文件主要有以下几个作用:

  1. 恢复:某些数据的恢复需要二进制文件。

  2. 复制:同另一台远程的mysql进行数据的同步。

  3. 审计:用于判断对数据库是否有进行注入攻击。

在mysql中二进制文件存在于datadir目录下,如下图所示:


二进制文件默认是没有启动的,我们需要手动的设置参数来启动它。但是启动二进制文件对数据库的整体性能会下降。但是对于数据库某一时刻宕机,对于数据的恢复是非常有用的。

MYSQL查看是否启用了日志show variables like 'log_bin';,若是没有开启也可以通过set命令将该值设置为on,查看当前的日志 show master status;,该日志文件的存放位置也是在datadir目录下

socket文件以及pid文件

该两类文件我们几乎很少涉及,该文件的存放为位置,直接可以查看my,cnf文件,这里就不进行深入了解。

表结构定义文件和存储引擎文件

表结构定义文件和表空间

*.frm 文件是所有mysql数据库都有的文件,记录了该表的表结构定义。InnoDB 中用于存储数据的文件总共有两个部分,一是系统表空间文件,包括 ibdata1ibdata2 等文件,其中存储了 InnoDB 系统信息和用户数据库表数据和索引,是所有表公用的,另一个是.idb文件,是每张表独有的。如下图所示:

当打开 innodb_file_per_table 选项时, .ibd 文件就是每一个表独有的表空间,文件存储了当前表的 数据,索引数据和插入缓冲等信息。查看和设置innodb_file_per_table 配置

show variables like '%per_table%';
set global innodb_file_per_table =ON;
重做日志文件

默认情况下在mysql的datadir下会有ib_logfile0ib_logfile1两个文件,这两个文件就是重做日志文件。重做日志文件的记录对于数据库的ACID事务中的 C(一致性) 提供了保障。每个innodb存储引擎中至少会有两个重做日志文件。

每个重做日志文件的大小是相同的,并且以循环的方式进行日志的写入,当ib_logfile0文件写满的时候,就会切换到ib_logfile1日志文件。

重做日志文件的功能和二进制日志文件功能同样是记录事务日志的文件,那么二进制文件和重做日志文件有什么区别呢?

  1. 二进制文件是记录所有和mysql数据库有关的日志文件,记录的范围比重做日志文件要广。

  2. 二进制文件仅在事务提交的时候刷入磁盘。而在事务进行中就会不断的将重做日志写入到磁盘中,

重做日志写入磁盘并不是直接写入,而是先写入到一个重做缓冲日志中,需要一定的条件触发才能进行写入。触发重做缓冲日志写入磁盘,一个是主线程(master thread),每秒会将重做日志刷入磁盘中。

另一个就是通过传参数innodb_flush_log_at_trx_commit参数来控制,该参数有0,1,2,其中0表示事务提交的时候不会将重做日志刷入磁盘中,需要主线程触发日志输出到磁盘中。

1表示事务commit的时候机会将缓冲区的日志输出到磁盘中。所以要事务的持久性和一致性将该值设置为1。在出现异常的时候,需要需要数据的恢复,便可以查看重做日志,并结合二进制日志文件进行数据的恢复。保证数据不会丢失。

[参考]

Mysql技术内幕innoDB存储引擎

[往期精彩回顾]

[万字长文,一文搞懂TCP/IP和HTTP、HTTPS]

[Mysql优化提高笔记整理,来自于一位鹅厂大佬的笔记]

[B树、B-树、B+树、B*树图文详解]

[万字长文,最硬核的mysql知识总结]

[为了把mysql的索引底层原理讲清楚,我把计算机翻了个底朝天]


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存